#include <soar.h>

struct thrd_ctl
{/*{{{*/
    unsigned long thrd_id;
    int thrd_idx;
    SOCKET sock;
};/*}}}*/

static void *thrd_func(struct thrd_ctl *thrd_ctl)
{/*{{{*/
    unsigned char *msg_in=NULL, *msg_out=NULL;
    int msg_in_size, msg_out_size;

    ALLOC_MULTI(msg_in, unsigned char, SOCK_MSG_SIZE, GO_OUT);
    //ALLOC_MULTI(msg_out, unsigned char, SOCK_MSG_SIZE, GO_OUT);

    printf("new thread(%d)\n", thrd_ctl->thrd_idx);

    while(1)
    {
        if(sock_read(thrd_ctl->sock, msg_in, &msg_in_size, -1, WRAP))
        {
            fprintf(stderr, "thread(%d): sock_read fail\n",
                thrd_ctl->thrd_idx);
            goto GO_OUT;
        }

        //memcpy(msg_out, msg_in, msg_in_size);
        msg_out=msg_in;
        msg_out_size=msg_in_size;
        if(sock_write(thrd_ctl->sock, msg_out, &msg_out_size, -1, WRAP))
        {
            fprintf(stderr, "thread(%d): sock_write fail\n",
                thrd_ctl->thrd_idx);
            goto GO_OUT;
        }
    }

GO_OUT:
    FREE(msg_in);
//    FREE(msg_out);
    sock_close(thrd_ctl->sock);
    return(NULL);
}/*}}}*/

int main(int argc, char *argv[])
{/*{{{*/
    int rtn;

    int server_port=20000;
    SOCKET listen_sock=sock_listen(server_port);
    if(listen_sock == INVALID_SOCKET)
    {
        fprintf(stderr, "socket listen fail\n");
        rtn=-1; goto GO_OUT;
    } 

    int thrd_idx=0;
    while(1)
    {
        SOCKET new_sock=sock_accept(listen_sock, -1);
        if(new_sock == INVALID_SOCKET)
        {
            fprintf(stderr, "socket accept fail\n");
            continue;
        }

        struct thrd_ctl *thrd_ctl;
        ALLOC(thrd_ctl, struct thrd_ctl, GO_OUT);
        thrd_ctl->thrd_idx=thrd_idx;
        thrd_idx++;
        thrd_ctl->sock=new_sock;
        if(thrd_create((THRD_FUNC_T)thrd_func,
                    (void *)thrd_ctl, THRD_DETACH,
                    &thrd_ctl->thrd_id))
        {
            printf("%s: thread create fail\n", __func__);
            rtn=-1; goto GO_OUT;
        }
    }

    rtn=0;

GO_OUT:
    sock_close(listen_sock);
    return(rtn);
}/*}}}*/
